package com.cskaoyan.javase.oop1._11static._1basic;

/**
 * 引例
 * 宠物公司新进了一批同样颜色的猫，创建一个类描述这批宠物
 * 注：创建该类时，给出一个静态成员变量和一个静态成员方法。
 *
 * static修饰的成员，称之为静态成员，包括静态成员变量和静态成员方法。
 * 静态成员的访问并不依赖于创建对象，可以直接通过类名访问
 * 其原因在于：
 * 随着类加载完毕，静态成员就存在，并且能够使用了:
 *      1.静态成员变量在类加载过程中完成默认初始化具有默认值，然后进行一些其它赋值，类加载结束就可以访问了。
 *      静态成员变量的赋值也是先进行默认初始化，然后考虑其它赋值手段。
 *
 *      2.静态成员方法的二进制指令集合在类加载过程也准备完毕，可以调用了。
 *          方法如何调用,是由方法的调用机制决定的
 *          成员方法,静态方法都是指令合集,但是:
 *              成员变量必须使用对象来调用
 *              静态成员变量无需对象,类名点就可以调用
 *          所以方法的调用我们无需过多的关注.
 *
 * 所以从今天开始,我们查看一个Java面向对象程序的执行,就要分成两个阶段:
 *      1.类加载的阶段
 *      2.new对象的阶段(创建对象的阶段)
 *
 * 以上,可以做总结/推导,思考以下问题:
 *      1.静态成员变量的初始化赋值都是在类加载过程中完成的,
 *          静态成员方法也有类似的过程
 *          所以访问类的静态成员会不会触发类加载呢?
 *          会触发
 *          这是一种类加载的时机
 *
 *      2.(最重要)类加载只有一次,那么类的静态成员变量对于某一个类来说,有几份?
 *          就只有一份
 *          静态成员变量在类的全局是独一无二的
 *          所以静态成员变量也称之为"全局变量"
 *
 *          而成员变量属于对象,存储在对象中,对象有几个,成员变量就有几份.
 *
 *      3.(重点)类加载在前,new对象在后,所以在内存中静态变量,成员变量谁先谁后出现呢?
 *          静态成员变量一定先出现
 *          成员变量一定后出现
 *
 * 一个Java面向对象程序的执行,拆分成两个阶段,用debug模式查看程序中方法进栈的情况,表现为:
 *      1.首先会类加载这个类
 *          表现在方法栈帧进栈上,就是该类的clinit方法栈帧进栈
 *          该方法是编译器自动封装完成的一个方法
 *              将在类加载过程中所有会执行的代码,按照执行顺序,封装成clinit方法
 *          目前已知的会在类加载过程中,执行的代码(会封装进clinit方法中的代码):
 *              静态成员变量的显式赋值
 *              特别强调: 方法不调用不执行,即便是静态方法,只不过意味着它的调用不需要对象,不意味着它在类加载过程中被自动调用.
 *
 *
 *       2.类加载完毕，clinit方法栈帧出栈。于是开始new对象过程，也就是找构造器
 *
 * @since 14:44
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // System.out.println(Cat.color);
        // Cat.sleep();
        Cat c = new Cat();
    }
}

class Cat {
    String name;
    static String color = "黑色";

    public void eat() {
        System.out.println(name + "正在吃饭~");
    }
    public static void sleep(){
        System.out.println("睡觉~~");
    }
}